<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <title>Servlet  &middot; sitename</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1">


<meta name="description" content="Servlet description" />

<meta name="keywords" content="one, two, ">


<meta property="og:title" content="Servlet  &middot; sitename ">
<meta property="og:site_name" content="sitename"/>
<meta property="og:url" content="https://lvzongcheng.gitee.io/java/servlet/" />
<meta property="og:locale" content="en-EN">


<meta property="og:type" content="article" />
<meta property="og:description" content="Servlet description"/>
<meta property="og:article:published_time" content="2017-05-13T00:00:00Z" />
<meta property="og:article:modified_time" content="2017-05-13T00:00:00Z" />

  
    
<meta property="og:article:tag" content="one">
    
<meta property="og:article:tag" content="two">
    
  

  

<script type="application/ld+json">
  {
    "@context": "http://schema.org",
    "@type": "Article",
    "headline": "Servlet",
    "author": {
      "@type": "Person",
      "name": "LvZongCheng"
    },
    "datePublished": "2017-05-13",
    "description": "Servlet description",
    "wordCount":  790 
  }
</script>



<link rel="canonical" href="https://lvzongcheng.gitee.io/java/servlet/" />

<link rel="apple-touch-icon-precomposed" sizes="144x144" href="https://lvzongcheng.gitee.io/touch-icon-144-precomposed.png">
<link href="https://lvzongcheng.gitee.io/favicon.png" rel="icon">

<meta name="generator" content="Hugo 0.60.0" />

  <!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

<link href='https://fonts.googleapis.com/css?family=Merriweather:300%7CRaleway%7COpen+Sans' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="/css/font-awesome.min.css">
<link rel="stylesheet" href="/css/style.css">
<link rel="stylesheet" href="/css/highlight/default.css">

  
  
	<script>
	  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
	  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
	  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
	  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

	  ga('create', 'Your Google Analytics tracking code', 'auto');
	  ga('send', 'pageview');

	</script>

</head>
<body>
  <main id="main-wrapper" class="container main_wrapper has-sidebar">
    <header id="main-header" class="container main_header">
  <div class="container brand">
  <div class="container title h1-like">
  <a class="baselink" href="https://lvzongcheng.gitee.io">
  LvZongCheng

</a>

</div>

  
<div class="container topline">
  
  淡定 执著 进取 自律


</div>


</div>

  <nav class="container nav primary no-print">
  

<a class="homelink" href="https://lvzongcheng.gitee.io">home</a>


  
<a href="https://lvzongcheng.gitee.io/framework" title="Show list of Frameworks">Frameworks</a>

<a href="https://lvzongcheng.gitee.io/java" title="Show list of Java">Java</a>

<a href="https://lvzongcheng.gitee.io/linux" title="Show list of Linux">Linux</a>

<a href="https://lvzongcheng.gitee.io/redis" title="Show list of Redis">Redis</a>

<a href="https://lvzongcheng.gitee.io/sql" title="Show list of SQL">SQL</a>

<a href="https://lvzongcheng.gitee.io/Spring" title="Show list of Spring">Spring</a>

<a href="https://lvzongcheng.gitee.io/tools" title="Show list of Tools">Tools</a>

<a href="https://lvzongcheng.gitee.io/webpage" title="Show list of WebPage">WebPage</a>

<a href="https://lvzongcheng.gitee.io/information" title="Show list of information">information</a>

<a href="https://lvzongcheng.gitee.io/network" title="Show list of network">network</a>

<a href="https://lvzongcheng.gitee.io/%E5%BE%AE%E6%9C%8D%E5%8A%A1" title="Show list of 微服务">微服务</a>

<a href="https://lvzongcheng.gitee.io/%E6%80%BB%E7%BB%93" title="Show list of 总结">总结</a>

<a href="https://lvzongcheng.gitee.io/%E6%9C%BA%E5%99%A8%E8%87%AA%E5%8A%A8%E5%8C%96" title="Show list of 机器自动化">机器自动化</a>

<a href="https://lvzongcheng.gitee.io/%E6%B1%87%E7%BC%96" title="Show list of 汇编">汇编</a>

<a href="https://lvzongcheng.gitee.io/%E8%AE%B0%E4%BA%8B%E6%9C%AC" title="Show list of 记事本">记事本</a>


</nav>

<div class="container nav secondary no-print">
  
<a id="contact-link-email" class="contact_link" rel="me" aria-label="Email" href="mailto:Lyc19880405@163.com">
  <span class="fa fa-envelope-square"></span></a>



<a id="contact-link-github" class="contact_link" rel="me" aria-label="Github" href="https://github.com/enten/hugo-boilerplate">
  <span class="fa fa-github-square"></span></a>




 


















</div>


  

</header>


<article id="main-content" class="container main_content single">
  <header class="container hat">
  <h1>Servlet
</h1>

</header>

  <div class="container content">
  <h3 id="servlet-">Servlet 概念</h3>
<p>Servlet是一种服务器端的Java应用程序，具有独立于平台和协议的特性，可以生成动态的Web页面。它担当客户请求（Web浏览器或其他HTTP客户程序）与服务器响应（HTTP服务器上的数据库或应用程序）的中间层。 Servlet是位于Web 服务器内部的服务器端的Java应用程序，与传统的从命令行启动的Java应用程序不同，Servlet由Web服务器进行加载，该Web服务器必须包含支持Servlet的Java虚拟机。</p>
<h3 id="servlet-1">Servlet 生命周期、工作原理</h3>
<ol>
<li>Servlet 生命周期：Servlet 加载&mdash;&gt;实例化&mdash;&gt;服务&mdash;&gt;销毁。</li>
<li>init（）：在Servlet的生命周期中，仅执行一次init()方法。它是在服务器装
入Servlet时执行的，负责初始化Servlet对象。可以配置服务器，以在启动服务
器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet，都
不会重复执行init（）。</li>
<li>service（）：它是Servlet的核心，负责响应客户的请求。每当一个客户请求
一个HttpServlet对象，该对象的Service()方法就要调用，而且传递给这个方法
一个“请求”（ServletRequest）对象和一个“响应”（ServletResponse）对
象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与
HTTP请求的方法相应的do功能。</li>
<li>destroy（）： 仅执行一次，在服务器端停止且卸载Servlet时执行该方法。当
Servlet对象退出生命周期时，负责释放占用的资源。一个Servlet在运行service()
方法时可能会产生其他的线程，因此需要确认在调用destroy()方法时，这些线程已
经终止或完成。</li>
</ol>
<p>Tomcat 与 Servlet 是如何工作的：</p>
<p><img src="/image/Java/20170605-01.jpg" alt="Alt text"></p>
<h6 id="heading">步骤：</h6>
<ol>
<li>Web Client 向Servlet容器（Tomcat）发出Http请求</li>
<li>Servlet容器接收Web Client的请求</li>
<li>Servlet容器创建一个HttpRequest对象，将Web Client请求的信息封装到这个对象中。</li>
<li>Servlet容器创建一个HttpResponse对象</li>
<li>Servlet容器调用HttpServlet对象的service方法，把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet 对象。</li>
<li>HttpServlet调用HttpRequest对象的有关方法，获取Http请求信息。</li>
<li>HttpServlet调用HttpResponse对象的有关方法，生成响应数据。</li>
<li>Servlet容器把HttpServlet的响应结果传给Web Client。</li>
</ol>
<h6 id="servlet">Servlet工作原理：</h6>
<ol>
<li>首先简单解释一下Servlet接收和响应客户请求的过程，首先客户发送一个请求，Servlet是调用service()方法对请求进行响应的，通过源代码可见，service()方法中对请求的方式进行了匹配，选择调用doGet,doPost等这些方法，然后再进入对应的方法中调用逻辑层的方法，实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet（）、doPost（）等等这些方法的，HttpServlet中定义了这些方法，但是都是返回error信息，所以，我们每次定义一个Servlet的时候，都必须实现doGet或doPost等这些方法。</li>
<li>每一个自定义的Servlet都必须实现Servlet的接口，Servlet接口中定义了五个方法，其中比较重要的三个方法涉及到Servlet的生命周期，分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的，不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet，因此HttpServlet也实现了Servlet接口。所以我们定义Servlet的时候只需要继承HttpServlet即可。</li>
<li>Servlet接口和GenericServlet是不特定于任何协议的，而HttpServlet是特定于HTTP协议的类，所以HttpServlet中实现了service()方法，并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。</li>
</ol>
<h6 id="servlet1">创建Servlet对象的时机：</h6>
<ol>
<li>Servlet容器启动时：读取web.xml配置文件中的信息，构造指定的Servlet对象，创建ServletConfig对象，同时将ServletConfig对象作为参数来调用Servlet对象的init方法。</li>
<li>在Servlet容器启动后：客户首次向Servlet发出请求，Servlet容器会判断内存中是否存在指定的Servlet对象，如果没有则创建它，然后根据客户的请求创建HttpRequest、HttpResponse对象，从而调用Servlet 对象的service方法。</li>
<li>Servlet Servlet容器在启动时自动创建Servlet，这是由在web.xml文件中为Servlet设置的<!-- raw HTML omitted -->属性决定的。从中我们也能看到同一个类型的Servlet对象在Servlet容器中以单例的形式存在。</li>
</ol>
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-xml" data-lang="xml"><span style="color:#f92672">&lt;servlet</span><span style="color:#f92672">&gt;</span>
        <span style="color:#f92672">&lt;servlet-name</span><span style="color:#f92672">&gt;</span>Init<span style="color:#f92672">&lt;/servlet-name&gt;</span>
        <span style="color:#f92672">&lt;servlet-class</span><span style="color:#f92672">&gt;</span>org.xl.servlet.InitServlet<span style="color:#f92672">&lt;/servlet-class&gt;</span>
        <span style="color:#f92672">&lt;load-on-startup</span><span style="color:#f92672">&gt;</span>1<span style="color:#f92672">&lt;/load-on-startup&gt;</span>
<span style="color:#f92672">&lt;/servlet&gt;</span>
</code></pre></div><hr>
<h3 id="jsp">JSP九种内置对象：</h3>
<h6 id="--request">一  request对象：</h6>
<p>该对象封装了用户提交的信息，通过调用该对象相应的方法可以获取封装的信息， 即使用该对象可以获取用户提交信息。 客户端的请求参数都被封装到这个对象里面</p>
<h6 id="--response">二  response对象：</h6>
<p>对客户的请求做出动态的响应，向客户端发送数据。</p>
<h6 id="--session">三  session对象</h6>
<ol>
<li>什么是session：session对象是一个JSP内置对象，它在第一个JSP页面被装载时自动创建，完成会话期管理。 
从一个客户打开浏览器并连接到服务器开始，到客户关闭浏览器离开这个服务器结束，被称为一个会话。当一个客户访问一个服务器时，可能会在这个服务器的几个页面之间反复连接，反复刷新一个页面，服务器应当通过某种办法知道这是同一个客户，这就需要session对象。</li>
<li>session对象的ID：当一个客户首次访问服务器上的一个JSP页面时，JSP引擎产生一个session对象，同时分配一个String类型的ID号，JSP引擎同时将这个ID号发送到客户端，存放在Cookie中，这样session对象和客户之间就建立了一一对应的关系。当客户再访问连接该服务器的其他页面时，不再分配给客户新的session对象，直到客户关闭浏览器后，服务器端该客户的session对象才取消，并且和客户的会话对应关系消失。当客户重新打开浏览器再连接到该服务器时，服务器为该客户再创建一个新的session对象。</li>
</ol>
<h6 id="--aplication">四  aplication对象</h6>
<ol>
<li>什么是application: 
服务器启动后就产生了这个application对象，当客户在所访问的网站的各个页面之间浏览时，这个application对象都是同一个，直到服务器关闭。但是与session不同的是，所有客户的application对象都是同一个，即所有客户共享这个内置的application对象。</li>
<li>application对象常用方法: 
(1)public void setAttribute(String key,Object obj): 将参数Object指定的对象obj添加到application对象中，并为添加的对象指定一个索引关键字。
(2)public Object getAttribute(String key): 获取application对象中含有关键字的对象。</li>
</ol>
<h6 id="-out">五 out对象</h6>
<pre><code>out 对象是一个输出流，用来向客户端输出数据。out对象用于各种数据的输出。
</code></pre>
<h6 id="--page-javalangobject">六  page java.lang.Object</h6>
<p>对应this关键字。JSP网页本身 
page对象是当前页面转换后的Servlet类的实例。从转换后的Servlet类的代码中，可以看到这种关系：</p>
<pre><code>Object page = this; 
</code></pre><p>在JSP页面中，很少使用page对象。</p>
<h6 id="--config">七  config</h6>
<p>javax.servlet. ServletConfig 的实例，该实例代表该JSP 的配置信息。常用的方法有getInitPararneter(String paramNarne) 及getInitPararneternarnes() 等方法。事实上， JSP 页面通常无须配置，也就不存在配置信息。因此，该对象更多地在Servlet 中有效。</p>
<h6 id="--exception-javalangthrowable-">八  exception java.lang.Throwable 的实例</h6>
<p>该实例代表其他页面中的异常和错误。只有当页面是错误处理页面，即编译指令page 的isErrorPage 属性为true 时，该对象才可以使用。常用的方法有getMessageO和printStackTraceO等。</p>
<h6 id="--pagecontext">九  pageContext</h6>
<p>javax.servlet.jsp.PageContext 的实例，对象直译时可以称作“页面上下文”对象，代表的是当前页面运行的一些属性，通过此对象可以拿到其他8大对象，使用该对象可以访问页面中的共享数据。常用的方法有getServletContextO和getServletConfigO等。</p>
<pre><code>//使用pageContext 设置属性，该属性默认在page 范围内 
pageContext. setAttribute (&quot;page&quot; , &quot;hello&quot;) ; 

  //使用request 设置属性，该属性默认在request 范围内 
request. setAttribute (&quot;request&quot; , &quot;hello&quot;); 

  //使用pageContext将属性设置在request 范围中 
pageContext.setAttribute(&quot;request2&quot; , &quot;hello&quot; , pageContext.REQUEST_SCOPE); 

  // 使用session将属性设置在session 范围中 
session.setAttribute(&quot;session&quot; , &quot;hello&quot;l; 

  //使用pageContext将属性设置在session范围中 
pageContext.setAttribute(&quot;session2&quot; , &quot;hello&quot; , pageContext.SESSION_SCOPE); 

  //使用application将属性设置在application范围中 
application. setAttribute (&quot;app&quot; , &quot;hello&quot;) ; 

  //使用pageContext 将属性设置在application 范围中 
pageContext.setAttribute(&quot;app2&quot; , &quot;hello&quot; , pageContext.APPL 工CATION_SCOPE) ;
</code></pre><hr>
<hr>
<h1 id="filterservletlistener">Filter、Servlet、Listener功能</h1>
<h2 id="1filter">1、Filter的功能</h2>
<p>filter功能，它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个request到达servlet之前预处理request,也可以在离开 servlet时处理response.换种说法,filter其实是一个”servlet chaining”(servlet 链).</p>
<p>一个Filter包括：</p>
<p>1）、在servlet被调用之前截获;</p>
<p>2）、在servlet被调用之前检查servlet request;</p>
<p>3）、根据需要修改request头和request数据;</p>
<p>4）、根据需要修改response头和response数据;</p>
<p>5）、在servlet被调用之后截获.</p>
<p>服务器每次只调用setFilterConfig方法一次准备filter 的处理;调用doFilter方法多次以处理不同的请求.FilterConfig接口有方法可以找到filter名字及初始化参数信息.服务器可以设置 FilterConfig为空来指明filter已经终结。</p>
<p>每一个filter从doFilter()方法中得到当前的request及response.在这个方法里,可以进行任何的针对request及 response的操作.(包括收集数据,包装数据等).filter调用chain.doFilter()方法把控制权交给下一个filter.一个 filter在doFilter()方法中结束.如果一个filter想停止request处理而获得对response的完全的控制,那它可以不调用下 一个filter</p>
<p>例子：</p>
<p>首先新建一个Filter</p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->
<pre><code>&lt;filter-mapping&gt;  
    &lt;filter-name&gt;LogFilter&lt;/filter-name&gt;  
    &lt;url-pattern&gt;/*&lt;/url-pattern&gt;  
&lt;/filter-mapping&gt;  
</code></pre>
<p><!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<p>springboot 中 HandlerInterceptor和Filter区别及使用
<a href="https://blog.csdn.net/yb546822612/article/details/102950040">https://blog.csdn.net/yb546822612/article/details/102950040</a></p>
<h2 id="2servlet">2、servlet功能</h2>
<h5 id="1servlet-">1．Servlet 是什么？</h5>
<p>　　&ndash;Servlet是使用Java Servlet 应用程序设计接口（API）及相关类和方法的 Java 程序。除了 Java Servlet API，Servlet 还可以使用用以扩展和添加到 API 的 Java 类软件包。Servlet 在启用 Java 的 Web 服务器上或应用服务器上运行并扩展了该服务器的能力。Java servlet对于Web服务器就好象Java applet对于Web浏览器。Servlet装入Web服务器并在Web服务器内执行，而applet装入Web浏览器并在Web浏览器内执行。Java Servlet API 定义了一个servlet 和Java使能的服务器之间的一个标准接口，这使得Servlets具有跨服务器平台的特性。
　　&ndash;Servlet 通过创建一个框架来扩展服务器的能力，以提供在 Web 上进行请求和响应服务。当客户机发送请求至服务器时，服务器可以将请求信息发送给 Servlet，并让 Servlet 建立起服务器返回给客户机的响应。 当启动 Web 服务器或客户机第一次请求服务时，可以自动装入 Servlet。装入后， Servlet 继续运行直到其它客户机发出请求。Servlet 的功能涉及范围很广。例如，Servlet 可完成如下功能：
　　&ndash;(1) 创建并返回一个包含基于客户请求性质的动态内容的完整的 HTML页面。
　　&ndash;(2) 创建可嵌入到现有 HTML 页面中的一部分 HTML 页面（HTML 片段）。
　　&ndash;(3) 与其它服务器资源（包括数据库和基于 Java 的应用程序）进行通信。
　　&ndash;(4) 用多个客户机处理连接，接收多个客户机的输入，并将结果广播到多个客户机上。例如，Servlet 可以是多参与者的游戏服务器。
　　&ndash;(5) 当允许在单连接方式下传送数据的情况下，在浏览器上打开服务器至applet的新连接，并将该连
接保持在打开状态。当允许客户机和服务器简单、高效地执行会话的情况下，applet也可以启动客户浏览器和服务器之间的连接。可以通过定制协议或标准（如 IIOP）进行通信。
　　&ndash;(6) 对特殊的处理采用 MIME 类型过滤数据，例如图像转换和服务器端包括（SSI）。
　　&ndash;(7) 将定制的处理提供给所有服务器的标准例行程序。例如，Servlet 可以修改如何认证用户。</p>
<h5 id="2servlet-">2．Servlet 的生命周期</h5>
<p>　　Servlet 的生命周期始于将它装入 Web 服务器的内存时，并在终止或重新装入 Servlet 时结束。</p>
<h6 id="1-">(1) 初始化</h6>
<p>　　在下列时刻装入 Servlet：
　如果已配置自动装入选项，则在启动服务器时自动装入
　在服务器启动后，客户机首次向 Servlet 发出请求时
　重新装入 Servlet 时装入 Servlet 后，服务器创建一个 Servlet 实例并且调用 Servlet 的 init() 方法。在初始化阶段，Servlet 初始化参数被传递给 Servlet 配置对象。</p>
<h6 id="2-">(2) 请求处理</h6>
<p>　　对于到达服务器的客户机请求，服务器创建特定于请求的一个“请求”对象和一个“响应”对象。服务器调用 Servlet 的 service() 方法，该方法用于传递“请求”和“响应”对象。service() 方法从“请求”对象获得请求信息、处理该请求并用“响应”对象的方法以将响应传回客户机。service() 方法可以调用其它方法来处理请求，例如 doGet()、doPost() 或其它的方法。</p>
<h6 id="3-">(3) 终止</h6>
<p>　　当服务器不再需要 Servlet, 或重新装入 Servlet 的新实例时，服务器会调用 Servlet 的 destroy() 方法。</p>
<h5 id="3-java-servlet-api">3. Java Servlet API</h5>
<p>　　&ndash;Java Servlet 开发工具（JSDK）提供了多个软件包，在编写 Servlet 时需要用到这些软件包。其中包括两个用于所有 Servlet 的基本软件包：javax.servlet 和 javax.servlet.http。可从sun公司的Web站点下载 Java Servlet 开发工具。 下面主要介绍javax.servlet.http提供的HTTP Servlet应用编程接口。
　　&ndash;HTTP Servlet 使用一个 HTML 表格来发送和接收数据。要创建一个 HTTP Servlet，请扩展 HttpServlet 类， 该类是用专门的方法来处理 HTML 表格的 GenericServlet 的一个子类。 HTML 表单是由 <!-- raw HTML omitted --> 和 <!-- raw HTML omitted --> 标记定义的。表单中典型地包含输入字段（如文本输入字段、复选框、单选按钮和选择列表）和用于提交数据的按钮。当提交信息时，它们还指定服务器应执行哪一个Servlet（或其它的程序）。 HttpServlet 类包含 init()、destroy()、service() 等方法。其中 init() 和 destroy() 方法是继承的。
&ndash;###### (1) init() 方法
　　&ndash;在 Servlet 的生命期中，仅执行一次 init() 方法。它是在服务器装入 Servlet 时执行的。 可以配置服务器，以在启动服务器或客户机首次访问 Servlet 时装入 Servlet。 无论有多少客户机访问 Servlet，都不会重复执行 init() 。
　　&ndash;缺省的 init() 方法通常是符合要求的，但也可以用定制 init() 方法来覆盖它，典型的是管理服务器端资源。 例如，可能编写一个定制 init() 来只用于一次装入 GIF 图像，改进 Servlet 返回 GIF 图像和含有多个客户机请求的性能。另一个示例是初始化数据库连接。缺省的 init() 方法设置了 Servlet 的初始化参数，并用它的 ServletConfig 对象参数来启动配置， 因此所有覆盖 init() 方法的 Servlet 应调用 super.init() 以确保仍然执行这些任务。在调用 service() 方法之前，应确保已完成了 init() 方法。
　　&ndash;###### (2) service() 方法
　　service() 方法是 Servlet 的核心。每当一个客户请求一个HttpServlet 对象，该对象的service() 方法就要被调用，而且传递给这个方法一个“请求”（ServletRequest）对象和一个“响应”（ServletResponse）对象作为参数。 在 HttpServlet 中已存在 service() 方法。缺省的服务功能是调用与 HTTP 请求的方法相应的 do 功能。例如， 如果 HTTP 请求方法为 GET，则缺省情况下就调用 doGet() 。Servlet 应该为 Servlet 支持的 HTTP 方法覆盖 do 功能。因为 HttpServlet.service() 方法会检查请求方法是否调用了适当的处理方法，不必要覆盖 service() 方法。只需覆盖相应的 do 方法就可以了。
　&ndash;当一个客户通过HTML 表单发出一个HTTP POST请求时，doPost（）方法被调用。与POST请求相关的参数作为一个单独的HTTP 请求从浏览器发送到服务器。当需要修改服务器端的数据时，应该使用doPost()方法。
　当一个客户通过HTML 表单发出一个HTTP GET请求或直接请求一个URL时，doGet()方法被调用。与GET请求相关的参数添加到URL的后面，并与这个请求一起发送。当不会修改服务器端的数据时，应该使用doGet()方法。
　　&ndash;Servlet的响应可以是下列几种类型：
　　&ndash;一个输出流，浏览器根据它的内容类型（如text/HTML）进行解释。
　　&ndash;一个HTTP错误响应, 重定向到另一个URL、servlet、JSP。
　　&ndash;###### (3) destroy() 方法
　　destroy() 方法仅执行一次，即在服务器停止且卸装Servlet 时执行该方法。典型的，将 Servlet 作为服务器进程的一部分来关闭。缺省的 destroy() 方法通常是符合要求的，但也可以覆盖它，典型的是管理服务器端资源。例如，如果 Servlet 在运行时会累计统计数据，则可以编写一个 destroy() 方法，该方法用于在未装入 Servlet 时将统计数字保存在文件中。另一个示例是关闭数据库连接。
当服务器卸装 Servlet 时，将在所有 service() 方法调用完成后，或在指定的时间间隔过后调用 destroy() 方法。一个Servlet 在运行service() 方法时可能会产生其它的线程，因此请确认在调用 destroy() 方法时，这些线程已终止或完成。
　　&ndash;###### (4) GetServletConfig（）方法
　　GetServletConfig（）方法返回一个 ServletConfig 对象，该对象用来返回初始化参数和　　ServletContext。ServletContext 接口提供有关servlet 的环境信息。
　　&ndash;###### (5) GetServletInfo（）方法
　　&ndash;GetServletInfo（）方法是一个可选的方法，它提供有关servlet 的信息，如作者、版本、版权。
　　&ndash;当服务器调用sevlet 的Service（）、doGet（）和doPost（）这三个方法时，均需要 “请求”和“响应”对象作为参数。“请求”对象提供有关请求的信息，而“响应”对象提供了一个将响应信息返回给浏览器的一个通信途径。javax.servlet 软件包中的相关类为ServletResponse和ServletRequest，而javax.servlet.http 软件包中的相关类为HttpServletRequest 和 HttpServletResponse。Servlet 通过这些对象与服务器通信并最终与客户机通信。Servlet 能通过调用“请求”对象的方法获知客户机环境，服务器环境的信息和所有由客户机提供的信息。Servlet 可以调用“响应”对象的方法发送响应，该响应是准备发回客户机的。
例子：</p>
<!-- raw HTML omitted -->
<p>import java.io.IOException;</p>
<p>import javax.servlet.ServletException;<br>
import javax.servlet.http.HttpServlet;<br>
import javax.servlet.http.HttpServletRequest;<br>
import javax.servlet.http.HttpServletResponse;</p>
<p>/**</p>
<ul>
<li>@author Administrator</li>
<li></li>
</ul>
<p>*/<br>
public class LogServlet extends HttpServlet {</p>
<pre><code>/** 
 *  
 */  
private static final long serialVersionUID = 1L;  

@Override  
protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
        throws ServletException, IOException {  
    doPost(req, resp);  
}  
  
@Override  
protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
        throws ServletException, IOException {  
    System.err.println(&quot;...doPost(req, resp)...&quot;);  
}  
</code></pre>
<p>}<br>
<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<!-- raw HTML omitted -->
<p><!-- raw HTML omitted -->  
<!-- raw HTML omitted -->LogServlet<!-- raw HTML omitted -->  
<!-- raw HTML omitted -->/*<!-- raw HTML omitted --><!-- raw HTML omitted -->  
<!-- raw HTML omitted --> 
<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<p>&ndash; ##### 它的拦截规则：
&ndash;当一个请求发送到servlet容器的时候，容器先会将请求的url减去当前应用上下文的路径作为servlet的映射url，比如我访问的是http://localhost/test/aaa.html，我的应用上下文是test，容器会将http://localhost/test去掉，剩下的/aaa.html部分拿来做servlet的映射匹配。这个映射匹配过程是有顺序的，而且当有一个servlet匹配成功以后，就不会去理会剩下的servlet了（filter不同，后文会提到）。其匹配规则和顺序如下：</p>
<p>&ndash;1.精确路径匹配。例子：比如servletA 的url-pattern为 /test，servletB的url-pattern为 /* ，这个时候，如果我访问的url为http://localhost/test ，这个时候容器就会先 进行精确路径匹配，发现/test正好被servletA精确匹配，那么就去调用servletA，也不会去理会其他的servlet了。</p>
<p>&ndash;2.最长路径匹配。例子：servletA的url-pattern为/test/<em>，而servletB的url-pattern为/test/a/</em>，此时访问http://localhost/test/a时，容器会选择路径最长的servlet来匹配，也就是这里的servletB。</p>
<p>&ndash;3.扩展匹配，如果url最后一段包含扩展，容器将会根据扩展选择合适的servlet。例子：servletA的url-pattern：*.action</p>
<p>&ndash;4.如果前面三条规则都没有找到一个servlet，容器会根据url选择对应的请求资源。如果应用定义了一个default servlet，则容器会将请求丢给default servlet</p>
<h2 id="3listener">3、Listener功能</h2>
<p>它是基于观察者模式设计的，Listener 的设计对开发 Servlet 应用程序提供了一种快捷的手段，能够方便的从另一个纵向维度控制程序和数据。目前 Servlet 中提供了 5 种两类事件的观察者接口，它们分别是：4 个 EventListeners 类型的，ServletContextAttributeListener、ServletRequestAttributeListener、ServletRequestListener、HttpSessionAttributeListener 和 2 个 LifecycleListeners 类型的，ServletContextListener、HttpSessionListener。如下图所示：</p>
<p><img src="/image/servlet/Listener_001.png" alt="Alt text"></p>
<p>&ndash;Listener是Servlet的监听器，它可以监听客户端的请求、服务端的操作等。通过监听器，可以自动激发一些操作，比如监听在线的用户的数量。当增加一个HttpSession时，就激发sessionCreated(HttpSessionEvent se)方法，这样就可以给在线人数加1。常用的监听接口有以下几个：</p>
<p>&ndash;ServletContextAttributeListener监听对ServletContext属性的操作，比如增加、删除、修改属性。</p>
<p>&ndash;ServletContextListener监听ServletContext。当创建ServletContext时，激发contextInitialized(ServletContextEvent sce)方法；当销毁ServletContext时，激发contextDestroyed(ServletContextEvent sce)方法。</p>
<p>&ndash;HttpSessionListener监听HttpSession的操作。当创建一个Session时，激发session Created(HttpSessionEvent se)方法；当销毁一个Session时，激发sessionDestroyed (HttpSessionEvent se)方法。</p>
<p>&ndash;HttpSessionAttributeListener监听HttpSession中的属性的操作。当在Session增加一个属性时，激发attributeAdded(HttpSessionBindingEvent se) 方法；当在Session删除一个属性时，激发attributeRemoved(HttpSessionBindingEvent se)方法；当在Session属性被重新设置时，激发attributeReplaced(HttpSessionBindingEvent se) 方法。</p>
<p>&ndash;下面我们开发一个具体的例子，这个监听器能够统计在线的人数。在ServletContext初始化和销毁时，在服务器控制台打印对应的信息。当ServletContext里的属性增加、改变、删除时，在服务器控制台打印对应的信息。</p>
<p>&ndash;要获得以上的功能，监听器必须实现以下3个接口：</p>
<p>&ndash;HttpSessionListener</p>
<p>&ndash;ServletContextListener</p>
<p>&ndash;ServletContextAttributeListener</p>
<!-- raw HTML omitted -->
<p>import javax.servlet.ServletContextAttributeEvent;<br>
import javax.servlet.ServletContextAttributeListener;<br>
import javax.servlet.ServletContextEvent;<br>
import javax.servlet.ServletContextListener;<br>
import javax.servlet.http.HttpSessionEvent;<br>
import javax.servlet.http.HttpSessionListener;</p>
<p>/**</p>
<ul>
<li>@author Administrator</li>
<li></li>
</ul>
<p>*/<br>
public class OnlineUserListener implements HttpSessionListener,<br>
ServletContextListener, ServletContextAttributeListener {<br>
private long onlineUserCount = 0;</p>
<pre><code>public long getOnlineUserCount() {  
    return onlineUserCount;  
}  

/* (non-Javadoc) 
 * @see javax.servlet.ServletContextAttributeListener#attributeAdded(javax.servlet.ServletContextAttributeEvent) 
 */  
@Override  
public void attributeAdded(ServletContextAttributeEvent arg0) {  

}  

/* (non-Javadoc) 
 * @see javax.servlet.ServletContextAttributeListener#attributeRemoved(javax.servlet.ServletContextAttributeEvent) 
 */  
@Override  
public void attributeRemoved(ServletContextAttributeEvent arg0) {  

}  

/* (non-Javadoc) 
 * @see javax.servlet.ServletContextAttributeListener#attributeReplaced(javax.servlet.ServletContextAttributeEvent) 
 */  
@Override  
public void attributeReplaced(ServletContextAttributeEvent attributeEvent) {  
    System.err.println(&quot;...attributeReplaced...&quot;);  
}  

/* (non-Javadoc) 
 * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) 
 */  
@Override  
public void contextDestroyed(ServletContextEvent arg0) {  

}  

/* (non-Javadoc) 
 * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
 */  
@Override  
public void contextInitialized(ServletContextEvent arg0) {  

}  

/* (non-Javadoc) 
 * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent) 
 */  
@Override  
public void sessionCreated(HttpSessionEvent httpSessionEvent) {  
    onlineUserCount ++;  
    toUpdateCount(httpSessionEvent);  
}  

/* (non-Javadoc) 
 * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent) 
 */  
@Override  
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {  
    onlineUserCount --;  
    toUpdateCount(httpSessionEvent);  
}  

private void toUpdateCount(HttpSessionEvent httpSessionEvent){  
    httpSessionEvent.getSession().setAttribute(&quot;onlineUserCount&quot;, onlineUserCount);  
}  
</code></pre>
<p>} 
<!-- raw HTML omitted --><!-- raw HTML omitted --></p>
<!-- raw HTML omitted -->
<!-- raw HTML omitted -->

</div>


  
</article>
      <footer id="main-footer" class="container main_footer">
  

  <div class="container nav foot no-print">
  
<a href="https://lvzongcheng.gitee.io/license">license</a>


  <a class="toplink" href="#">back to top</a>

</div>

  <div class="container credits">
  
<div class="container footline">
  
  code with <!-- raw HTML omitted --><!-- raw HTML omitted -->


</div>


  
<div class="container copyright">
  
  (c) 2015 yourname.


</div>


</div>

</footer>

    </main>
    
<script type="text/javascript">
  (function() {
    
    
    if (window.location.hostname == "localhost")
      return;
    var dsq = document.createElement('script'); dsq.async = true; dsq.type = 'text/javascript';
    dsq.src = '//your_disqus_shortname.disqus.com/count.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
  })();
</script>



<script src="/js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



    
  </body>
</html>

